package me.zhengjie.modules.website.repository;

import me.zhengjie.modules.website.domain.ContentTable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;

import javax.persistence.criteria.Predicate;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.*;
import java.util.Date;

/**
 * @author system
 * @since 2024-09-26 16:41:54
 */
@Component
public class ContentTableSpecifications {
    public static Specification<ContentTable> queryList(ContentTable contentTable) {
        return (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            // 通过反射遍历 ContentTable 的所有字段，过滤静态字段
            for (Field field : ContentTable.class.getDeclaredFields()) {
                field.setAccessible(true); // 允许访问私有字段

                // 跳过静态字段
                if (Modifier.isStatic(field.getModifiers())) {
                    continue;
                }

                try {
                    Object value = field.get(contentTable); // 获取字段值
                    if (value != null) {
                        // 对 title 字段使用模糊匹配
                        if ("title".equals(field.getName())) {
                            predicates.add(criteriaBuilder.like(root.get(field.getName()), "%" + value + "%"));
                        } else {
                            predicates.add(criteriaBuilder.equal(root.get(field.getName()), value));
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            // **过滤掉超出范围的 releaseTime**
            Predicate validReleaseTime = criteriaBuilder.between(
                    root.get("releaseTime"),
                    Timestamp.valueOf("1000-01-01 00:00:00"),
                    Timestamp.valueOf("9999-12-31 23:59:59")
            );
            predicates.add(validReleaseTime);

            // **添加排序规则**
            Expression<Integer> sortOrderExpression = root.get("sortOrder");
            Expression<LocalDateTime> releaseTimeExpression = root.get("releaseTime");

            // 排序规则1：先按照 sortOrder 降序排列，sortOrder 越大越靠前
            Order sortOrderSort = criteriaBuilder.desc(criteriaBuilder.coalesce(sortOrderExpression, -1));

            // 排序规则2：再按照 releaseTime 降序排列，releaseTime 为 null 的排到最后
            Expression<Object> safeReleaseTime = criteriaBuilder.selectCase()
                    .when(criteriaBuilder.isNull(releaseTimeExpression), Timestamp.valueOf("1000-12-31 23:59:59"))
                    .otherwise(releaseTimeExpression);
            Order releaseTimeSort = criteriaBuilder.desc(safeReleaseTime);

            // 将排序规则添加到查询中
            query.orderBy(sortOrderSort, releaseTimeSort);

            // 返回最终的查询条件和排序规则
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
    }





   /* public static Specification<ContentTable> queryList(ContentTable contentTable) {
        return (root, query, builder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (contentTable.getContentId() != null) {
                predicates.add(builder.like(root.get("contentId" ).as(String.class),  contentTable.getContentId() + "" ));
            }
            if (contentTable.getTitle() != null) {
                predicates.add(builder.like(root.get("title" ).as(String.class), "%" + contentTable.getTitle() + "%" ));
            }
            if (contentTable.getSubtitle() != null) {
                predicates.add(builder.like(root.get("subtitle" ).as(String.class), "%" + contentTable.getSubtitle() + "%" ));
            }
            if (contentTable.getBody() != null) {
                predicates.add(builder.like(root.get("body" ).as(String.class), "%" + contentTable.getBody() + "%" ));
            }
            if (contentTable.getCoverImage() != null) {
                predicates.add(builder.like(root.get("coverImage" ).as(String.class), "%" + contentTable.getCoverImage() + "%" ));
            }
            if (contentTable.getLinkUrl() != null) {
                predicates.add(builder.like(root.get("linkUrl" ).as(String.class), "%" + contentTable.getLinkUrl() + "%" ));
            }
            if (contentTable.getIsDownloadable() != null) {
                predicates.add(builder.like(root.get("isDownloadable" ).as(String.class), "%" + contentTable.getIsDownloadable() + "%" ));
            }
            if (contentTable.getStatus() != null) {
                predicates.add(builder.like(root.get("status" ).as(String.class), "%" + contentTable.getStatus() + "%" ));
            }
            if (contentTable.getColumnIds() != null) {
                predicates.add(builder.equal(root.get("columnId" ).as(Long.class), contentTable.getColumnIds()));
            }
            if (contentTable.getAttachmentPath() != null) {
                predicates.add(builder.like(root.get("attachmentPath" ).as(String.class), "%" + contentTable.getAttachmentPath() + "%" ));
            }
            if (contentTable.getViewCount() != null) {
                predicates.add(builder.equal(root.get("viewCount" ).as(Integer.class), contentTable.getViewCount()));
            }
            if (contentTable.getLikeCount() != null) {
                predicates.add(builder.equal(root.get("likeCount" ).as(Integer.class), contentTable.getLikeCount()));
            }
            if (contentTable.getIsPinned() != null) {
                predicates.add(builder.like(root.get("isPinned" ).as(String.class), "%" + contentTable.getIsPinned() + "%" ));
            }
            if (contentTable.getSortOrder() != null) {
                predicates.add(builder.equal(root.get("sortOrder" ).as(Integer.class), contentTable.getSortOrder()));
            }
            Predicate[] p = new Predicate[predicates.size()];
            return query.where(builder.and(predicates.toArray(p))).getRestriction();
        };
    }*/

}

